package com.fjec.activity.service.impl;

import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjec.activity.entity.*;
import com.fjec.activity.feign.BaseClient;
import com.fjec.activity.feign.MarketClient;
import com.fjec.activity.mapper.*;
import com.fjec.activity.service.IBizExchangeGiftService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjec.activity.view.ExchangeGiftVO;
import com.fjec.activity.view.UserCashingBankVO;
import com.fjec.common.enums.EnumSysCode;
import com.fjec.common.exception.BizException;
import com.fjec.common.jxls.ExchangeGiftExcel;
import com.fjec.common.protocol.JsonResult;
import com.fjec.common.setting.Setting;
import com.fjec.common.shiro.AccountInfo;
import com.fjec.common.util.BusinessUtil;
import com.fjec.common.util.DateUtil;
import com.fjec.common.util.SequenceIdGenerator;
import com.fjec.common.view.DevopsExchangeGiftVO;
import com.fjec.common.view.ServiceProjectVO;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 * 010.兑换礼物表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2020-12-08
 */
@Service
public class BizExchangeGiftServiceImpl extends ServiceImpl<BizExchangeGiftMapper, BizExchangeGift> implements IBizExchangeGiftService {

    @Resource
    private BizExchangeGiftMapper mapper;

    @Resource
    private BizUserGiftMapper userGiftMapper;

    @Resource
    private BizExchangeGiftDetailMapper exchangeGiftDetailMapper;

    @Resource
    private InfoUserCashingBankMapper userCashingBankMapper;

    @Resource
    private BizUserGiftChangeRecordMapper userGiftChangeRecordMapper;

    @Resource
    private MarketClient marketClient;

    @Resource
    private BaseClient baseClient;

    @Resource
    private SequenceIdGenerator idGenerator;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public JsonResult userExchangeGift(String ids, String giftIds, String nums) throws Exception {
        Long exchangeId = idGenerator.nextId();
        String[] strUserGiftIds = ids.split(",");
        String[] strGiftIds = giftIds.split(",");
        String[] strNums = nums.split(",");
        // 获取兑换范围
        Map<String, Object> tmpMap = baseClient.getSysSetting();
        Setting setting = new Setting(tmpMap);
        Integer min = setting.getExchangeGiftMin();
        Integer max = setting.getExchangeGiftMax();
        // 获取礼物数据
        Map<String, ServiceProjectVO> servProjList = marketClient.getServiceProjectByIds(giftIds);
        // 更新兑换礼物详细数据
        StringBuilder sbGiftDetail = new StringBuilder();
        int totalAmount = 0;
        for (int i = 0; i < strUserGiftIds.length; i++) {
            Long userGiftId = Long.valueOf(strUserGiftIds[i]);
            Long giftId = Long.valueOf(strGiftIds[i]);
            Integer num = Integer.valueOf(strNums[i]);
            // 获取用户礼物数据
            BizUserGift userGiftEntity = userGiftMapper.selectById(userGiftId);
            // check用户礼物数据是否够用
            int giftNumber = userGiftEntity.getGiftNum() - num;
            if (giftNumber < 0) {
                throw new BizException(EnumSysCode.ERR_3029.getCode(), EnumSysCode.ERR_3029.getMsg());
            }
            // 更新用户礼物数量
            userGiftEntity.setGiftNum(giftNumber);
            userGiftEntity.setUpdateTime(DateUtil.nowLdt());
            int count = userGiftMapper.updateById(userGiftEntity);
            if (count <= 0) {
                throw new BizException(EnumSysCode.ERR_3029.getCode(), EnumSysCode.ERR_3029.getMsg());
            }
            // 获取礼物信息
            ServiceProjectVO servProjView = servProjList.get(giftId.toString());
            // 插入兑换礼物详细表
            int amount = num * servProjView.getAmount();
            BizExchangeGiftDetail egdEntity = new BizExchangeGiftDetail();
            egdEntity.setNum(num);
            egdEntity.setPrice(servProjView.getAmount());
            egdEntity.setAmount(amount);
            egdEntity.setExchangeId(exchangeId);
            egdEntity.setGiftId(giftId);
            egdEntity.setGiftSnapshot(servProjView.toMap());
            egdEntity.setCreateTime(DateUtil.nowLdt());
            exchangeGiftDetailMapper.insert(egdEntity);
            // 记录变化日志
            BizUserGiftChangeRecord recordEntity = new BizUserGiftChangeRecord();
            recordEntity.setOpeType(6);
            recordEntity.setNum(-1 * num);
            recordEntity.setBusiData(exchangeId.toString());
            recordEntity.setUserGiftId(userGiftId);
            recordEntity.setCreateTime(DateUtil.nowLdt());
            userGiftChangeRecordMapper.insert(recordEntity);
            // 计算总价格
            totalAmount += amount;
            //
            sbGiftDetail.append(servProjView.getServName()).append("×").append(num);
            if (i != strUserGiftIds.length - 1) {
                sbGiftDetail.append(",");
            }
        }
        // check总价格是否在范围之内
        if (totalAmount < min * 100 || totalAmount > max * 100) {
            throw new BizException(EnumSysCode.ERR_3028.getCode(),
                    String.format(EnumSysCode.ERR_3028.getMsg(), min, max));
        }
        // 获取代付银行信息
        QueryWrapper<InfoUserCashingBank> queryCashingBank = new QueryWrapper<>();
        queryCashingBank.eq("UserId", AccountInfo.getUserId());
        InfoUserCashingBank cashingBankEntity = userCashingBankMapper.selectOne(queryCashingBank);
        if (cashingBankEntity == null) {
            throw new BizException(EnumSysCode.ERR_3027.getCode(), EnumSysCode.ERR_3027.getMsg());
        }
        UserCashingBankVO cashingBankView = new UserCashingBankVO();
        BeanUtils.copyProperties(cashingBankView, cashingBankEntity);
        // 获取用户店铺信息
        Map<String, Object> shopInfo = new HashMap<>();
        shopInfo.put("busiType", AccountInfo.getBusiType());
        shopInfo.put("busiId", AccountInfo.getBusiId());
        shopInfo.put("shopName", AccountInfo.getShopName());
        // 保存兑换礼物信息
        BizExchangeGift entity = new BizExchangeGift();
        entity.setId(exchangeId);
        entity.setBusiType(AccountInfo.getBusiType());
        entity.setBusiId(AccountInfo.getBusiId());
        entity.setUserId(AccountInfo.getUserId());
        entity.setPercent(new BigDecimal(setting.getExchangeGiftPercent()));
        entity.setAmount(totalAmount);
        entity.setGiftStr(sbGiftDetail.toString());
        entity.setShopInfo(shopInfo);
        entity.setCashingBank(cashingBankView.toMap());
        entity.setCreateTime(DateUtil.nowLdt());
        mapper.insert(entity);
        return JsonResult.success()
                .message(combMessage(entity.getGiftStr(), entity.getAmount(), entity.getPercent()))
                .build();
    }

    @Override
    public JsonResult getExchangeGiftList() throws Exception {
        Map<String, Object> tmpMap;
        // 查询兑换信息
        QueryWrapper<BizExchangeGift> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("UserId", AccountInfo.getUserId());
        queryWrapper.orderByDesc("CreateTime");
        List<BizExchangeGift> entityList = mapper.selectList(queryWrapper);
        List<BizExchangeGiftDetail> detailEntityList = exchangeGiftDetailMapper.getDetailListByUserId(AccountInfo.getUserId());
        List<ExchangeGiftVO> resultList = new ArrayList<>();
        for (BizExchangeGift entity : entityList) {
            ExchangeGiftVO view = new ExchangeGiftVO();
            BeanUtils.copyProperties(view, entity);
            // 计算佣金
            BigDecimal bTotalAmount = new BigDecimal(entity.getAmount());
            BigDecimal bAmount = bTotalAmount.multiply(entity.getPercent());
            BigDecimal commission = bTotalAmount.subtract(bAmount);

            view.setCommission(String.valueOf(commission.setScale(0, RoundingMode.HALF_UP).doubleValue()));
            view.setExchangeAmount(String.valueOf(bAmount.setScale(0, RoundingMode.HALF_UP).doubleValue()));
            // 整理详情数据
            List<Map<String, Object>> detailMapList = new ArrayList<>();
            for (BizExchangeGiftDetail detailEntity : detailEntityList) {
                if (detailEntity.getExchangeId().longValue() == entity.getId().longValue()) {
                    tmpMap = new HashMap<>();
                    tmpMap.put("amount", detailEntity.getPrice());
                    tmpMap.put("giftName", MapUtils.getString(detailEntity.getGiftSnapshot(), "servName"));
                    tmpMap.put("requireNum", detailEntity.getNum());
                    tmpMap.put("servPic", MapUtils.getString(detailEntity.getGiftSnapshot(), "servPic"));
                    detailMapList.add(tmpMap);
                }
            }
            view.setDetailList(detailMapList);
            resultList.add(view);
        }
        return JsonResult.success()
                .data(resultList)
                .build();
    }

    @Override
    public Map<String, Object> getExchangeGiftPage(Page page, Integer searchBy, String condition, LocalDate startTime, LocalDate endTime) throws Exception {
        Map<String, Object> resultMap = new HashMap<>();
        // 计算当日时间上限下限
        LocalDateTime sTime = null;
        LocalDateTime eTime = null;
        if (startTime != null) {
            sTime = LocalDateTime.of(startTime, LocalTime.MIN);
        }
        if (endTime != null) {
            eTime = LocalDateTime.of(endTime, LocalTime.MAX);
        }
        Page<BizExchangeGift> returnPage = null;
        if (StringUtils.isEmpty(condition)) {
            returnPage = mapper.getExchangeGiftPage(page, searchBy, null, sTime, eTime);
        } else {
            returnPage = mapper.getExchangeGiftPage(
                    page,
                    searchBy,
                    searchBy == 1 ? "%" + condition + "%" : condition,
                    sTime,
                    eTime
            );
        }
        List<DevopsExchangeGiftVO> resultList = new ArrayList<>();
        for (BizExchangeGift entity : returnPage.getRecords()) {
            DevopsExchangeGiftVO view = new DevopsExchangeGiftVO();
            BeanUtils.copyProperties(view, entity);
            view.setShopName(MapUtils.getString(entity.getShopInfo(), "shopName"));
            // 身份类别
            view.setBusiStr(BusinessUtil.busiType2Str(entity.getBusiType()));
            // 计算数据
            BigDecimal bTotalAmount = new BigDecimal(entity.getAmount());
            BigDecimal bAmount = bTotalAmount.multiply(entity.getPercent());
            BigDecimal commission = bTotalAmount.subtract(bAmount);
            view.setCommission(String.valueOf(commission.setScale(0, RoundingMode.HALF_UP).doubleValue()));
            view.setExchangeAmount(String.valueOf(bAmount.setScale(0, RoundingMode.HALF_UP).doubleValue()));
            // 加入列表
            resultList.add(view);
        }
        resultMap.put("total", returnPage.getTotal());
        resultMap.put("list", resultList);
        return resultMap;
    }

    @Override
    public List<ExchangeGiftExcel> getExchangeGiftForExcel(LocalDate localDate) {
        // 计算时间
        LocalDateTime startTime = LocalDateTime.of(localDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
        // 查询数据
        int i = 1;
        List<BizExchangeGift> entityList = mapper.getExchangeGiftByDate(startTime, endTime);
        List<ExchangeGiftExcel> dataList = new ArrayList<>();
        for (BizExchangeGift entity : entityList) {
            ExchangeGiftExcel view = new ExchangeGiftExcel();
            view.setExchangeId(entity.getId().toString());
            view.setNumber(i++);
            view.setProv(MapUtils.getString(entity.getCashingBank(), "bankProvince"));
            view.setCity(MapUtils.getString(entity.getCashingBank(), "bankCity"));
            view.setBankName(MapUtils.getString(entity.getCashingBank(), "bankName"));
            view.setAccount(MapUtils.getString(entity.getCashingBank(), "accountNo"));
            view.setName(MapUtils.getString(entity.getCashingBank(), "accountName"));
            view.setPhone(MapUtils.getString(entity.getCashingBank(), "phone"));
            // 计算
            BigDecimal amount = new BigDecimal(entity.getAmount());
            amount = amount.multiply(entity.getPercent()).divide(new BigDecimal(100));
            view.setAmount(String.valueOf(amount.setScale(2, RoundingMode.HALF_UP).doubleValue()));
            dataList.add(view);
        }
        return dataList;
    }

    private String combMessage(String giftDetail, Integer totalAmount, BigDecimal percent) {
        String message = "礼物兑换申请提交成功，若银行账户信息无误，本次兑换的金额将于5个工作日内转入您的银行账户，请留意账户余额变动！本次兑换：%s，价值合计：%s元；平台佣金：%s元；应结算金额：%s元。";
        BigDecimal bTotalAmount = new BigDecimal(totalAmount).divide(new BigDecimal(100));
        BigDecimal bAmount = bTotalAmount.multiply(percent);
        BigDecimal commission = bTotalAmount.subtract(bAmount);
        return String.format(
                message,
                giftDetail,
                bTotalAmount.setScale(2, RoundingMode.HALF_UP).doubleValue(),
                commission.setScale(2, RoundingMode.HALF_UP).doubleValue(),
                bAmount.setScale(2, RoundingMode.HALF_UP).doubleValue()
        );
    }
}
